#include "tickcountrunner.hpp"

int TickCountRunner::m_runnerId = 0;

TickCountRunner::TickCountRunner()
{
    m_threadList.clear();
}


TickCountRunner::~TickCountRunner()
{
    // Stop all running worker threads
    while (!m_threadList.isEmpty())
    {
        TickCountRunnable *runner = m_threadList.takeFirst();
	runner->stop();

        // Wait for the thread to end
        if (runner->wait(1000))
        {
            qWarning() << "Cannot stop Runner: " << runner->objectName();
        }

        delete runner;
    }
}


void TickCountRunner::startRunners(int count)
{
    // Check if there are already enough workers
    if (m_threadList.size() >= count)
    {
        return;
    }

    // Get the desired worker count
    int workerCount = (count > 0) ? count : (QThread::idealThreadCount());

    for (int i = m_threadList.size(); i < workerCount; i++)
    {
        // Create a new Thread
        TickCountRunnable *runner = TickCountRunnableFactory::getNativeTickCountRunner();
        runner->setObjectName("TickCountRunnable_" + QString::number(++m_runnerId));
	runner->setProperty("id", m_runnerId);
	connect (runner, SIGNAL(finished()), SLOT(onRunnerFinished()));

	// Start the Thread
        runner->start();
        m_threadList.append(runner);
    }
}


int TickCountRunner::stopRunners(int count)
{
    // Check if there is any worker to stop
    if (m_threadList.size() == 0)
    {
        return 0;
    }

    // If no correct amount is given, stop all threads
    if (count <= 0)
    {
	count = m_threadList.size();
    }

    do {
        // Stop the Thread
	TickCountRunnable *runner = m_threadList.takeFirst();
	runner->stop();

        // Wait for the thread to end
	if (!runner->wait(1000))
        {
            qWarning() << "Cannot stop Runner: " << runner->objectName();
        }

        --count;
    } while (count > 0 && !m_threadList.isEmpty());

    return m_threadList.size();
}


void TickCountRunner::onRunnerFinished()
{
    // Get the Thread who sent this signal
    TickCountRunnable *runner = qobject_cast<TickCountRunnable*>(QObject::sender());

    // Check if it is still in the list and remove it
    if (m_threadList.contains(runner))
    {
        m_threadList.removeOne(runner);
    }

    // Delete the Thread
    runner->deleteLater();
}
